package com.zhangsun.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangsun.expection.BusinessException;
import com.zhangsun.system.component.SystemComponent;
import com.zhangsun.system.entity.DepartmentEntity;
import com.zhangsun.system.entity.ResourceEntity;
import com.zhangsun.system.entity.RoleResourceEntity;
import com.zhangsun.system.mapper.DepartmentMapper;
import com.zhangsun.system.service.DepartmentService;
import com.zhangsun.system.vo.department.DepartmentEditVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 部门 服务实现类
 * </p>
 *
 * @author zhangsun
 * @since 2019-08-12
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, DepartmentEntity> implements DepartmentService {

    @Autowired
    private SystemComponent systemComponent;

    @Override
    public List<DepartmentEntity> findAll(String deptId) {
        LambdaQueryWrapper<DepartmentEntity> queryWrapper = new QueryWrapper<DepartmentEntity>().lambda();
        if (StrUtil.isNotBlank(deptId)) {
            queryWrapper.ne(DepartmentEntity::getId, deptId);
        }
        List<DepartmentEntity> departments = baseMapper.selectList(queryWrapper);
        return systemComponent.getDepartmentTree(departments);
    }

    @Override
    public void create(DepartmentEditVo vo) {
        if (StrUtil.isBlank(vo.getParentId())) {
            LambdaQueryWrapper<DepartmentEntity> queryWrapper = new QueryWrapper<DepartmentEntity>().lambda();
            queryWrapper.isNull(DepartmentEntity::getParentId);
            int count = baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException("只能有一个顶级部门");
            }
        }

        DepartmentEntity departmentEntity = new DepartmentEntity();
        BeanUtil.copyProperties(vo, departmentEntity);
        departmentEntity.insert();
    }

    @Override
    public DepartmentEntity findById(String id) {
        DepartmentEntity department = baseMapper.selectById(id);
        if (department != null) {
            List<String> parentIds = new ArrayList<>();
            findParentId(department.getParentId(), parentIds);
            department.setParentIds(parentIds);
        }
        return department;
    }

    private void findParentId(String parentId, List<String> parentIds) {
        if (StrUtil.isNotBlank(parentId)) {
            parentIds.add(0, parentId);
            DepartmentEntity department = baseMapper.selectById(parentId);
            if (department != null) {
                findParentId(department.getParentId(), parentIds);
            }
        }
    }

    @Override
    public void update(String id, DepartmentEditVo vo) {
        if (StrUtil.isBlank(vo.getParentId())) {
            LambdaQueryWrapper<DepartmentEntity> queryWrapper = new QueryWrapper<DepartmentEntity>().lambda();
            queryWrapper.isNull(DepartmentEntity::getParentId)
                    .ne(DepartmentEntity::getId, id);
            int count = baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException("只能有一个顶级部门");
            }
        }

        DepartmentEntity departmentEntity = new DepartmentEntity();
        BeanUtil.copyProperties(vo, departmentEntity);
        departmentEntity.setId(id);
        departmentEntity.updateById();
    }

    @Override
    public void delete(String id) {
        List<String> departmentIds = new ArrayList<>();
        departmentIds.add(id);
        findChildrenId(id, departmentIds);
        baseMapper.deleteBatchIds(departmentIds);
    }

    private void findChildrenId(String id, List<String> childrenIds) {
        LambdaQueryWrapper<DepartmentEntity> queryWrapper = new QueryWrapper<DepartmentEntity>().lambda();
        queryWrapper.eq(DepartmentEntity::getParentId, id);
        List<DepartmentEntity> departments = baseMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(departments)) {
            departments.forEach(item -> {
                childrenIds.add(item.getId());
                findChildrenId(item.getId(), childrenIds);
            });
        }
    }
}
